from time import sleep
import random
import sys
from base64 import b64decode
from PyQt5.QtCore import QThread,pyqtSignal,QDateTime,Qt,QPoint
from PyQt5.QtGui import QIcon,QPixmap,QImage,QPainter, QPen,QCursor
from PyQt5.QtWidgets import QMainWindow,QWidget,QAction,QGridLayout,QLabel,QDesktopWidget,QApplication,QPushButton,QMessageBox,QLineEdit,QTextEdit
from keras.preprocessing import image
from PIL import Image

import AICore as aic

#系统配置

class BackendThread(QThread):
    update_date = pyqtSignal(str)

    def run(self):
        while True:
            data = QDateTime.currentDateTime()
            currtime = data.toString("yyyy-MM-dd hh:mm:ss")
            self.update_date.emit(str(currtime))
            sleep(1)





class Window(QMainWindow):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        self.ww = 820
        self.wh = 450

        self.resize(self.ww, self.wh)

        # 初始化窗口样式
        # self.setWindowFlags(Qt.FramelessWindowHint)
        # self.setWindowFlags(Qt.WindowMinimizeButtonHint)
        self.setWindowOpacity(0.95)
        self.setWindowFlags(Qt.FramelessWindowHint)

        self.status = self.statusBar()
        self.status.showMessage("Train @^@")

        
        with open("./tricon.dll","r",encoding='utf-8') as ms:
            self.icobase = str(ms.read())


        self.qrPixmap = QPixmap(QImage.fromData(b64decode(self.icobase)))
        self.setWindowIcon(QIcon(self.qrPixmap))

        self.uptitle = "基于机器学习的数字识别程序"
        self.setWindowTitle(self.uptitle)

        #资料属性
        self.titletext = "基于机器学习的数字识别程序"
        # setMouseTracking设置为False，否则不按下鼠标时也会跟踪鼠标事件
        self.setMouseTracking(False)

        self.pos_xy = []  # 保存鼠标移动过的点

        self.center()

        #%%%%%%%%%%%%%%%%%%%%%%%% 控件 %%%%%%%%%%%%%%%%%%%%%%%
        self.title = QLabel(self)
        self.setObjectName("title")
        self.title.setText(self.titletext)
        self.title.resize(800,30)
        self.title.setAutoFillBackground(True)
        self.title.setStyleSheet("font: 75 15pt '微软雅黑';"
                                 "color: white; "
                                 "background-color:orange ; "
                                 "font-weight:bold;"

                                 "border:2px inset rgb(200, 150, 120); "
                                 "border-radius:15%; padding-left:5px; padding-right:10px;"
                                 )


        self.label1 = QLabel(self)
        self.label1.setObjectName("label1")
        self.label1.setText("输入框")
        self.label1.resize(400,400)
        self.label1.setAutoFillBackground(True)
        self.label1.setStyleSheet("font: 75 13pt '微软雅黑';"
                                  "border:1px inset rgb(20, 100, 150); "
                                  "color:rgb(100, 50, 160); "
                                  "background-color:'white'; "
                                  "font-weight:bold;"
                                  
                                  "border-radius:20%; padding-left:5px; padding-right:10px;"
                                  )
        


        self.label2 = QLabel(self)
        self.label2.setObjectName("label2")
        self.label2.setText("<p align='center'>识别结果</p>")
        self.label2.resize(400, 400)
        self.label2.setAutoFillBackground(True)
        self.label2.setStyleSheet("font: 75 20pt '微软雅黑';"
                                  "border:2px outset rgb(95, 158, 160); "
                                  "color:gray; "
                                  "background-color:white; "
                                  "font-weight:bold;"
                                  
                                  "border-radius:20%; padding-left:5px; padding-right:10px;"
                                  )

        self.b1 = QPushButton(self)
        self.b1.setObjectName("b1")
        self.b1.setText("帮助文档")
        self.b1.setDefault(True)
        self.b1.setStyleSheet("font-size:15px; font-family:微软雅黑;"
                              "border:2px solid gray;"
                              
                              "border-radius:10%; padding-left:2px; padding-right:2px; padding-top:3px; padding-bottom:3px;")
        self.b1.clicked.connect(self.b1_clicked)

        self.b2 = QPushButton(self)
        self.b2.setObjectName("b2")
        self.b2.setText("识别数字")
        self.b2.setDefault(True)
        self.b2.setStyleSheet("font-size:15px; font-family:微软雅黑;"
                              "border:2px solid purple;"
                              
                              "border-radius:10%; padding-left:2px; padding-right:2px; padding-top:3px; padding-bottom:3px;"

                              )
        self.b2.clicked.connect(self.b2_clicked)

        self.b3 = QPushButton(self)
        self.b3.setObjectName("b3")
        self.b3.setText("清空画布")
        self.b3.setDefault(True)
        self.b3.setStyleSheet("font-size:15px; font-family:微软雅黑;"
                              "border:2px solid black;"
                              
                              "border-radius:10%; padding-left:2px; padding-right:2px; padding-top:3px; padding-bottom:3px;")
        self.b3.clicked.connect(self.b3_clicked)

        self.b4 = QPushButton(self)
        self.b4.setObjectName("b4")
        self.b4.setText("退出")
        self.b4.setDefault(True)
        self.b4.setStyleSheet("font-size:15px; font-family:微软雅黑;"
                              "border:2px solid #B22222;"
                              
                              "border-radius:10%; padding-left:2px; padding-right:2px; padding-top:3px; padding-bottom:3px;")
        self.b4.clicked.connect(self.b4_clicked)


        #@@@ 多线程 @@@#

        # 时间更新多线程
        self.backend = BackendThread()
        self.backend.update_date.connect(self.Wintitle_update)
        self.backend.start()

        #$$$$ 布局 $$$$#

        vlayout = QGridLayout(self)
        vlayout.addWidget(self.title, 1, 1, 1, 4)
        vlayout.addWidget(self.label1, 2, 1,8,2)
        vlayout.addWidget(self.label2, 2, 3, 8, 2)
        vlayout.addWidget(self.b1, 10, 1)
        vlayout.addWidget(self.b2,10,2)
        vlayout.addWidget(self.b3, 10, 3)
        vlayout.addWidget(self.b4, 10, 4)


        widget = QWidget()
        widget.setLayout(vlayout)
        self.setCentralWidget(widget)


        #$$$$ end $$$$#

        # 绘图区定义
        self.pos_xy = []  # 保存鼠标移动过的点

        self.pix = QPixmap(380, 380)
        self.pix.fill(Qt.white)
        self.label1.setPixmap(self.pix)
        self.lastPoint = QPoint()
        self.endPoint = QPoint()
        
        self.m_drag = False



    def Wintitle_update(self,hud):
        self.title.setText(str(self.titletext)+" | "+str(hud))

    def b1_clicked(self):
        try :
            with open("./help.dll","r",encoding='utf-8') as fso:
                self.helptext = str(fso.read())

            if len(self.helptext) < 10:
                self.helptext = "帮助文档丢失或损坏。"

        except:
                self.helptext = "帮助文档丢失或损坏。"

        QMessageBox.information(self,"帮助及说明",str(self.helptext),QMessageBox.Yes,QMessageBox.Yes)

    def b2_clicked(self):
        self.b2.setEnabled(False)
        self.status.showMessage("Train 正在识别中...")

        print("画笔轨迹 | "+str(self.pos_xy))

        fnme1 = "./dealwith.png"

        screen = QApplication.primaryScreen()
        screenshot = screen.grabWindow(self.label1.winId())
        sds = screenshot.toImage()
        sds.save(fnme1,"png")

        sleep(1)

        self.btn_recognize_on_clicked(fnme1)

        
        
        

    def b3_clicked(self):
        self.pos_xy = []
        self.label1.setPixmap(self.pix)
        self.label2.setText("<p align='center'>识别结果</p>")
        self.update()

    def b4_clicked(self):
        self.close()

    #手写函数
    def paintEvent(self, event):
        if self.m_drag == False:

            pp = QPainter(self.label1.pixmap())

            pen = QPen(Qt.black, 30, Qt.SolidLine)
            pp.setPen(pen)

            if len(self.pos_xy) > 1:
                point_start = self.pos_xy[0]
                for pos_tmp in self.pos_xy:
                    point_end = pos_tmp

                    if point_end == (-1, -1):
                        point_start = (-1, -1)
                        continue
                    if point_start == (-1, -1):
                        point_start = point_end
                        continue

                    pp.drawLine(point_start[0], point_start[1], point_end[0], point_end[1])
                    point_start = point_end

            pp.end()

    def mouseMoveEvent(self, event):
        '''
            按住鼠标移动事件：将当前点添加到pos_xy列表中
        '''
        # 中间变量pos_tmp提取当前点
        if self.m_drag == False:

            pos_tmp = (event.pos().x(), event.pos().y())
            # pos_tmp添加到self.pos_xy中
            self.pos_xy.append(pos_tmp)

            self.update()

        if Qt.RightButton and self.m_drag:
            self.label1.setEnabled(False)
            self.move(event.globalPos() - self.m_dragposition)
            event.accept()
            
        self.update()

    def mousePressEvent(self, event):
        if event.button() == Qt.RightButton:
            self.label1.setEnabled(False)
            self.m_drag = True
            self.m_dragposition = event.globalPos()-self.pos()
            event.accept()
            self.setCursor(QCursor(Qt.OpenHandCursor))

            
    def mouseReleaseEvent(self, event):
        '''
            重写鼠标按住后松开的事件
            在每次松开后向pos_xy列表中添加一个断点(-1, -1)
        '''

        #窗口移动
        self.m_drag = False
        self.label1.setEnabled(True)
        self.setCursor(QCursor(Qt.ArrowCursor))

        self.update()

        if self.m_drag == False and event.button() == Qt.LeftButton:
            pos_test = (-1, -1)
            self.pos_xy.append(pos_test)

        self.update()

    
    #加载神经网络
    work_network = aic.__init__("high.h5")
    
    def post_to_network(self,imname):
        """
        把图片文件递给神经网络
        @parem image
        @return answer

        answer: 0~9
        """      
        img = Image.open(imname)
        img = img.resize((28,28),Image.HAMMING) # 采样(插值)
        img = image.img_to_array(img)[:,:,0]# RGB 只保留单通道
        img = 255 - img #反色
        
        data = img.reshape(1,28*28).astype('float')
        return self.work_network.predict_classes(data)
    
    
    def btn_recognize_on_clicked(self,im):
        #bbox = (104, 104, 380, 380)
        #im = ImageGrab.grab(bbox)   # 截屏，手写数字部分

        recognize_result = self.post_to_network(im)  # 调用识别函数
        self.label2.setText("<p align='center'><font size='5'>"+str(recognize_result)+"</font></p>")  # 显示识别结果
        self.b2.setEnabled(True)
        self.status.showMessage("Train 识别完成 @#@",3000)
        self.update()

        



    # 居中显示 #
    def center(self):
        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.wx = (screen.width() - size.width()) / 2
        self.wy = (screen.height() - size.height()) / 2

        # self.setSize(self.winwidth, self.winheight)
        self.setFixedSize(self.ww, self.wh)

        self.move(int(self.wx), int(self.wy))






if __name__ == "__main__":
    app = QApplication(sys.argv)

    win = Window()

    qssstyle = '''
        QPushButton#b1:hover{background-color:gray;}
        QPushButton#b2:hover{background-color:purple; color:white}
        QPushButton#b3:hover{background-color:silver; color:gray}
        QPushButton#b4:hover{background-color:#B22222; color:white;}
        
        QPushButton#b1:pressed{color:purple;}
        QPushButton#b2:pressed{color:'orange';}
        QPushButton#b3:pressed{color:'white';}
        QPushButton#b4:pressed{color:red;}
        
    
    
    
    '''
    win.setStyleSheet(qssstyle)

    win.show()

    sys.exit(app.exec_())









#F5F5DC



